//
// Created by denglibin on 19-4-14.
//

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>


/**
重定向编程 dup和dup2函数,函数dup和dup2提供了复制文件描述符的功能
他们通常用于stdin,stdout或进程的stderr的重定向。一般来说，普通输出函数（如：printf），默认是将某信息写入到文件描述符为1的文件中，
普通输入函数都默认从文件描述符为0的文件中读取数据。
因此重定向操作实际上是关闭某个标准输入输出设备（文件描述符为0、1、2），
而将另一个打开的普通文件的文件描述符设置为0、1、2.
   输入重定向：关闭标准输入设备，打开（或复制）某普通文件，使其文件描述符为0.
   输出重定向：关闭标准输出设备，打开（或复制）某普通文件，使其文件描述符为1.
   错误输出重定向：关闭标准错误输入设备，打开（或复制）某普通文件，使其文件描述符为2.

dup函数

头文件：#include<unistd.h>
定义函数：
    int dup(int oldfd);

函数dup 允许你复制一个oldfd文件描述符。存入一个已存在的文件描述符，它就会返回一个与该描述符“相同”的新的文件描述符。
即这两个描述符共享相同的内部结构，共享所有的锁定，读写位置和各项权限或flags等等。例如：对一个文件描述符进行了lseek操作，
另一个文件描述符的读写位置也会随之改变。不过，文件描述符之间并不共享close-on-exec flags.
    返回值：如成功则返回新的文件描述符，否则出错返回-1.注意：由dup函数返回的新文件描述符一定是当前可用文件描述符中的最小值。
*/
static int main_(int argc, char** argv)
{
    int fd,newFd; //定义两个文件描述符
    char * str = "Advanced Programming! write by fd\n";
    char * newStr = "Advanced Programming! write by newFd\n";
    /*
O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR   读写模式

O_APPEND每次写操作都写入文件的末尾
O_CREAT如果指定文件不存在，则创建这个文件
O_EXCL如果要创建的文件已存在，则返回-1，并且修改errno的值
O_TRUNC如果文件存在，并且以只写/读写方式打开，则清空文件全部内容(即将其长度截短为0)
O_NOCTTY如果路径名指向终端设备，不要把这个设备用作控制终端。
O_NONBLOCK如果路径名指向FIFO/块文件/字符文件，则把文件的打开和后继I/O
*/
    fd = open("test.txt",O_RDWR|O_CREAT,0644); //打开文件
    if(fd==-1)
    {
        printf("open file error%m\n");
        exit(-1);
    }
    //开始复制了
    newFd = dup(fd);
    //使用fd写
    write(fd, str, strlen(str));
    close(fd);
    //使用newfd写
    write(newFd, newStr, strlen(newStr));
    int i = close(newFd);
    if(i == -1)
    {
        printf("close error\n");
    }
    return 0;
}
